/*
    Matali Physics Demo
    Copyright (c) 2011 KOMIRES Sp. z o. o.
 */
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using Komires.MataliPhysics;

namespace MataliPhysicsDemo
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class HeightmapDraw1
    {
        Demo demo;
        PhysicsScene scene;
        string instanceIndexName;

        DemoMesh heightmapMesh;
        bool dynamicUpdate;

        Matrix projection;
        Matrix view;
        Matrix world;

        Vector3 lightDirection;
        Vector3 lightDiffuse;
        Vector3 lightSpecular;

        public HeightmapDraw1(Demo demo, int instanceIndex)
        {
            this.demo = demo;
            instanceIndexName = " " + instanceIndex.ToString();

            heightmapMesh = new DemoMesh(demo);
        }

        public void Initialize(PhysicsScene scene)
        {
            this.scene = scene;

            dynamicUpdate = false;
        }

        public void UpdateResources()
        {
            if (heightmapMesh.Dynamic && (heightmapMesh.Vertices != null))
                dynamicUpdate = true;
        }

        public void SetControllers()
        {
            PhysicsObject objectBase = scene.Factory.PhysicsObjectManager.Find("Heightmap " + instanceIndexName);
            if (objectBase != null)
            {
                objectBase.UserControllers.EnableDraw = false;
                objectBase.UserControllers.DrawMethods += new DrawMethod(Draw);
                heightmapMesh = demo.Meshes[objectBase.UserTagStr];
            }
        }

        public void Draw(DrawMethodArgs args)
        {
            PhysicsScene scene = demo.Engine.Factory.PhysicsSceneManager.Get(args.OwnerSceneIndex);
            PhysicsObject objectBase = scene.Factory.PhysicsObjectManager.Get(args.OwnerIndex);

            PhysicsObject physicsObjectWithActiveCamera = scene.GetPhysicsObjectsWithActiveCamera(0);

            if (physicsObjectWithActiveCamera == null) return;

            PhysicsCamera activeCamera = physicsObjectWithActiveCamera.Camera;

            if (activeCamera == null) return;

            if ((heightmapMesh.Vertices != null) && heightmapMesh.Dynamic && (objectBase.Shape.ShapePrimitive.DynamicUpdate || dynamicUpdate))
            {
                dynamicUpdate = false;
                objectBase.Shape.GetMeshVertices(1.0f, 1.0f, false, true, heightmapMesh.Vertices);
                heightmapMesh.SetVertices(heightmapMesh.Vertices);
            }

            float time = args.Time;

            objectBase.MainWorldTransform.GetTransformMatrix(ref world);
            activeCamera.View.GetViewMatrix(ref view);
            activeCamera.Projection.GetProjectionMatrix(ref projection);

            PhysicsLight sceneLight = scene.Light;
            sceneLight.GetDirection(ref lightDirection);
            sceneLight.GetDiffuse(ref lightDiffuse);
            sceneLight.GetSpecular(ref lightSpecular);

            BasicEffect effect = heightmapMesh.Effect;

            effect.View = view;
            effect.World = world;
            effect.Projection = projection;

            effect.DirectionalLight0.Direction = lightDirection;
            effect.DirectionalLight0.DiffuseColor = lightDiffuse;
            effect.DirectionalLight0.SpecularColor = lightSpecular;
            effect.DirectionalLight0.Enabled = true;
            effect.LightingEnabled = true;
            effect.PreferPerPixelLighting = true;

            heightmapMesh.Draw(objectBase.Material, false);
        }
    }
}
